package com.game.raceroom.player	
{
	import com.game.raceroom.Room;
	import com.game.raceroom.player.contrl.Contrl;
	import com.game.raceroom.player.contrl.SideClipContrl;
	import com.game.raceroom.player.disp.ActorDisplayer;
	
	import flash.utils.getTimer;
	
	import mx.core.UIComponent;

	public class Player extends  Contrl
	{
		public var currentSystemTime:Number;
		public var userInfo:UserInfo;
		public var carInfo:CarInfo;
		//实际x,y坐标
		public var _x:Number;
		public var _y:Number;
		//视觉x,y坐标
		public var _viewx:Number=0;
		public var _viewy:Number=0;
		//x,y轴的误差
		public var _errx:Number=0;
		public var _erry:Number=0;
		//x,y轴贞修正值
		public var _fixx:Number=10;
		public var _fixy:Number=10;
		
		public var  max_blood:Number=1500;
		public var  now_blood:Number=1500;
		public var  max_str:Number=2000;
		public var  now_str:Number=2000;
		private var confChk:ConflictChecker;

		//汽车的角度
		public var _angle:int;
		public var actorDisp:ActorDisplayer;
		public var _speed,up_speed,down_speed,_vx,_vy:Number;
 
		public var _parent:Room;
        public var wasCrashedInThisFrame:Boolean=false;
        public var angleChanged:Boolean=false;
        public var isActor:Boolean=false;
        
	    public var _up,_down,_left,_right:Boolean;
	    public var sideClipContrl:SideClipContrl;
		//转弯时前进损失动力，增加侧滑动力中
		public var _accCft:Number=0.2;
		
		public var _braCft:Number=0.6;
		//总失力率
        public var totalLostCft:Number;
        
		public var _brake_up,_brake_down:Boolean;
		public var last_keypress_code:int=-1;
		public var last_keyrelease_code:int=-1;
		public var keypress_code:int=-1;
		public var keyrelease_code:int=-1;
		public var mapInfo:MapInfo;
	    //刹车
		public var _brake:Boolean=false;
		//松开油门
		public var _relaseAccelerator:Boolean=true;
	 
	    public var action:Action;
        public var actionCode:int;

        public var actionId:int=0;
        public static var i0:int=0;
        public static var i1:int=1;
        public static var i2:int=2;
        public static var i15:int=15;
        public static var i360:int=360;
        public var ready:Boolean=false;
        public var combo:Number=0;
        public var teamId:int=0;
        public static const MAX_COMBO=20;
		public function Player(gameCanvas:UIComponent,userInfo:UserInfo,mapInfo:MapInfo,parent:Room)
		{
			super(gameCanvas);
			this._parent=parent;
		    this.userInfo=userInfo;
		    this.mapInfo=mapInfo;
			carInfo=userInfo.currentCar;

			this.controlCft*=mapInfo.firctCft;
			sideClipContrl=new SideClipContrl(this);
			_braCft=mapInfo.firctCft*carInfo.braCft*carInfo.getSlipResistance()*controlCft;
			trace(_braCft +"  _braCft");
             _accCft=carInfo.accCft*carInfo.getSlipResistance()*controlCft;
		    _vx=i0;
		    _vy=i0;
		    up_speed=i0;
		    down_speed=i0;
		    _speed=i0;
		    confChk=new ConflictChecker(this);
		    action=new Action(this);
			actorDisp=new ActorDisplayer(gameCanvas);
			actorDisp.setActorInfo(this);
		    actorDisp.drawFirst(carInfo.car.iid);
			max_blood=carInfo.endure;
			now_blood=max_blood;
			actorDisp.initBloodBar(this.max_blood,this.now_blood);

		}
		public function setReady(ready:Boolean){
			if(ready)
			   actorDisp.setReady(ready);
			else
			   actorDisp.setReady(ready);
		}
        var showDeadEnd:Boolean=false;
		public function showActor():void{
			if(!dead){
			 	actorDisp.drawActor(_viewx,_viewy);
			}
		    else{
		    	if(!showDeadEnd){
			    	var step:int=Math.floor((getTimer()-deadTime)/200);
			    	switch(step){
			    	   case 0:
			    	   actorDisp.hide(0.8);
			    	   break;
			    	   case 1:
			    	   actorDisp.hide(0.5);
			    	   break;
			    	   case 2:
			    	   actorDisp.hide(0.8);
			    	   break;
			    	   case 3:
			    	   actorDisp.hide(1);
			    	   break;
			    	   case 4:
			    	   actorDisp.hide(0.8);
			    	   break;
			    	   case 5:
			    	   actorDisp.hide(0.5);
			    	   break;
			    	   case 6:
			    	   actorDisp.hide(0.8);
			    	   break;
			    	   case 7:
			    	   actorDisp.hide(1);
			    	   break;
			    	   case 8:
			    	   actorDisp.hide(0.8);
			    	   break;
			    	   case 9:
			    	   actorDisp.hide(0.5);
			    	   break;
			    	   case 10:
			    	   actorDisp.hide(0.8);
			    	   break;
			    	   case 11:
			    	   actorDisp.hide(1);
			    	   break;
			    	   case 12:
			    	   actorDisp.hide(0.8);
			    	   break;
			    	   case 13:
			    	   actorDisp.hide(0.5);
			    	   break;
			    	   case 14:
			    	   actorDisp.hide(0.3);
			    	   break;
			    	   case 15:
			    	   actorDisp.hide(0.2);
			    	   break;
			    	   default:
			    	   
			    	   if(!this.isActor){
			    	   	actorDisp.destory();
			    	   }else{
			    	   	actorDisp.hide(0.2);
			    	   
			    	   }
			    	   showDeadEnd=true;   	
			    	   break;
			    	}
		    	}
		    	actorDisp.drawActor(_viewx,_viewy);
		    }	 
		}
		private var alpha:int;
 
        public var attackTime:int=0;
        public function addFlash(time:int):void{
        	attackTime=time;
        }
        public var dead:Boolean=false;
        public var _dvx,_dvy:Number;
        public var weight:Number=1200;
        public var deadTime:Number;
		public function refBlood(blood:int):void{
        	if(dead)return;
        	now_blood=blood;
        	if(now_blood<=i0){
        		now_blood=i0;
        		this.dead=true;
        		this.resetAction();
        		this.deadTime=getTimer();
        	}
        	//trace("blood   "+now_blood+" "+blood);
        	
        	actorDisp.refreshBloodBar(max_blood,now_blood);
        }  

		public function showAttack():void{

			attackTime-=moveRuntime;
			if(attackTime<=i0){
				actorDisp.setAttack(i0);
			}else{
				actorDisp.setAttack(i1);
			}
			
		}
		
		public function turnActor():void{
				actorDisp.turnActor(_angle);
		}

        public function prepared():void{

 
			down_speed=i0;
			up_speed=i0;
			_speed=i0;

            turnActor();
            showActor();
            this.actorDisp.visible=true;
        }


        
        private var abs_x,abs_y:Number;
        public function onMoveAction(angle:int,x:Number, y:Number,
			 sideClipAngle:Number,sideClipSpeed:Number,up_speed:Number, down_speed:Number,
			 actionId:int,acode:int):void{
      		 trace("this                  "+_x+"  "+_y+"  "+up_speed+"  "+sideClipSpeed);
		    if(this._angle!=angle){
      		    _angle=angle;
      		    turnActor();
            }
//            abs_x=Math.abs(_x-x);
//            abs_y=Math.abs(_y-y);
//            if(abs_x>10)this._x=x;
//    		if(abs_y>10)this._y=y;
            cacuErrAndFix(x,y);
    		this.up_speed=up_speed;
    		this.down_speed=down_speed;
    		this.sideClipContrl.sideClipAngle=sideClipAngle;
    		this.sideClipContrl.speed=sideClipSpeed;
    		if(this.sideClipContrl.speed>i0){
    			sideClipContrl.hasSideClip=true;
    		}
    		action.parseActionCode(acode);
    		resetRunParam();
    		    	
        }
        var terrx,terry:Number;
        var tdiv,tmax:Number;
        public function cacuErrAndFix(x:Number,y:Number):void{
            this._viewx=_x;
            this._viewy=_y;
            
            this._x=x;
    	    this._y=y;
    	    this._errx=_viewx-_x;
    	    this._erry=_viewy-_y;
    	    terrx=Math.abs(_errx);
    	    terry=Math.abs(_erry);
    	    tmax=Math.max(terrx,terry);
    	    if(tmax<=3){
    	    	tdiv=1;
    	    }else{
    	    
	    	    tdiv= Math.sqrt(tmax);
	    	    if(tdiv>50){
	    	    	tdiv=50;
	    	    }
    	    }
  
    	    this._fixx=(this._errx/tdiv);
    	    this._fixy=(this._erry/tdiv);
    	    _fixx=Math.abs(_fixx);
    	    _fixy=Math.abs(_fixy);
    	    if(_fixx<1)_fixx=1;
    	    if(_fixy<1)_fixy=1;	
        }
        public function onAction(angle:int,
			 acode:int):void{
		    if(this._angle!=angle){
      		    _angle=angle;
      		    turnActor();
            }
    		action.parseActionCode(acode);
    		resetRunParam();
    		    	
        }
        public function resetRunParam():void{
    		    turnCoupling=i0;
    		    moveActionStartTime=getTimer();
    		    turnActionStartTime=moveActionStartTime;
        }

	public	var hasAction:Boolean;

    public  function update():void{
    	currentSystemTime=getTimer();
    	hasAction=false;
    	this.cacuRuntime();
    	fixErr();
		if(hasAction){
			checkPosition();
		}

    }
    private function fixErr():void{
    	if(_errx!=0){
    		if(_errx>0){
    			_errx-=_fixx;
    			if(_errx<0)_errx=0;
    		}else{
    			_errx+=_fixx;
    			if(_errx>0)_errx=0;
    		}
    	//	trace(_errx);
    		_viewx=_x+_errx;
    	}else{
    		_viewx=_x;
    	}
    	if(_erry!=0){
    		if(_erry>0){
    			_erry-=_fixy;
    			if(_erry<0)_erry=0;
    		}else{
    			_erry+=_fixy;
    			if(_erry>0)_erry=0;
    		}
    		_viewy=_y+_erry;
    		
    	}else{
    		_viewy=_y;
    	}
    }
 
	public function refreshBloodBar(nowBlood:int,dec:int):void{
		this.now_blood=nowBlood+dec;
		this.actorDisp.refreshBloodBar(this.max_blood,this.now_blood);
	}
	private var temp,temp1:Number;
    public function checkPosition():void{
    	temp=_x-carInfo.confRadius;
    	if(temp<mapInfo.map_x)_x=mapInfo.map_x+carInfo.confRadius;
    	temp=_y-carInfo.confRadius;
    	if(temp<mapInfo.map_y)_y=mapInfo.map_y+carInfo.confRadius;
    	temp=_x+carInfo.confRadius;
    	temp1=mapInfo.map_width-i1;
    	if(temp>temp1)_x=mapInfo.map_width-carInfo.confRadius-i1;
    	temp=_y+carInfo.confRadius;
    	temp1=mapInfo.map_height-i1;
    	if(temp>temp1)_y=mapInfo.map_height-carInfo.confRadius-i1;
    }
    
	private var moveRuntime:Number=0;
	private var stopRuntime:Number=0;
	private var turnRuntime:Number=0;
	//转向时段平均速度
    private var turnCoupling:Number=0;
    public var controlCft:Number=0.55;
    private var runCoupling:Number=0;
    public function resetAction():void{
    	actionCode=i0;
    	action.parseActionCode(actionCode);
    }
    public function setAction(acode:int):void{
    	actionCode=acode;
    	action.parseActionCode(acode);
    }
    public function cacuRuntime():void{
    	if(_left||_right){
            turnRuntime=currentSystemTime-turnActionStartTime;
            moveRuntime=currentSystemTime-moveActionStartTime;
            turnActionStartTime=currentSystemTime;
            moveActionStartTime=currentSystemTime;
            runCoupling=turnCoupling;
			turnCoupling+=carInfo.turnCft*turnRuntime;
			if(turnCoupling>=i15){
				 moveRuntime=(i15-runCoupling)/carInfo.turnCft;
				 move();
                 turn();
                 turnCoupling-=i15;
				 while(turnCoupling>i15){
					moveRuntime=i15/carInfo.turnCft;
					move();	
			     	turn();
                	turnCoupling-=i15;
				 }	
			 	 moveRuntime=turnCoupling/carInfo.turnCft;
			 	 move();
				 
			}else{
	             move();
			}
    	}else{
        	moveRuntime=currentSystemTime-moveActionStartTime;
       		moveActionStartTime=currentSystemTime;
       		move();
    	}
    }
   
    public function turn():void{
        // trace(_x+"  "+_y);
    	if(_up||_down){
           //转向时刻的速度损失与侧滑数据计算
           //controlCft 操控系数，雪地 公路 草地等不同
			if(_up){
				sideClipContrl.setSideClipData(controlCft,up_speed,_angle);
			}else{
				sideClipContrl.setSideClipData(controlCft,down_speed,_angle);
			} 
    		if(_up){
				if(_left)
					_angle=_angle-i15; 
				if(_right) 
					_angle=_angle+i15; 
    		}else{
				if(_left)
					_angle=_angle+i15; 
				if(_right) 
					_angle=_angle-i15; 
    		}
    	}else{
			if(_left)
				_angle=_angle-i15; 
			if(_right) 
				_angle=_angle+i15; 
    	}
		if(_angle>=i360){
			_angle=_angle%i360;
		}
		if(_angle<i0){
			_angle=_angle+i360;
		}

		turnActor();	
    }
    public function move():void{
    	if(_up){
    		hasAction=true;
    		moveUp();
    	}else if(_down){
    		hasAction=true;
    		moveDown();
    	}else{
    		if(sideClipContrl.hasSideClip){
    			hasAction=true;
    			moveBySideClip();
    		}
    	}
    }
   private  var startTime,nowTime:Number=0;
    private var t0,t1,t2,V=0,V0,V1,a,startV,endV:Number;
    public var turnActionStartTime:Number=0;
    public var moveActionStartTime:Number=0;
    public var stopActionStartTime:Number=0;
    public function go(speed:Number):Number{
			//时段平均速度 V=(t0*a+t2*a)/2
			//如果末速度大于最大速 
			    //V0=(t0*a+t1*a)/2;  V1=max
		    	//V=(V0*(t1-t0)+V1*(t2-t1))/(t2-t0)
		    //转向时刻加速度无效
		  //  if(_left||_right)return speed;
		    V=speed;
		    if(_up)
		    	V1=carInfo.maxUpSpeed;
		    else
		    	V1=carInfo.maxDownSpeed;
		    if(V<V1){
		    	a= _accCft;
		    	startTime=V/a;
		    	nowTime=moveRuntime+startTime;
		    	t0=	startTime;
		    	t2= nowTime;
				startV=t0*a;
				endV=t2*a;
				if(endV>V1){
					t1=V1/a;
					endV=t1*a;
					V0=(startV+endV)/i2;
					V=(V0*(t1-t0)+V1*(t2-t1))/(t2-t0);
				}else{
					V=(startV+endV)/i2;
				}
		       if(_up){
			    	up_speed=endV;
			    	if(up_speed>=carInfo.maxUpSpeed){
			    		up_speed=carInfo.maxUpSpeed;
			    		V=up_speed;
			    	}
		       }
			   else{
			    	down_speed=endV;
				    if(down_speed>=carInfo.maxDownSpeed){
			    		down_speed=carInfo.maxDownSpeed;
			    		V=down_speed;
			    	}
			   }
		    }	
		    return V;
        }

		public function brake(speed:Number):Number{
			//if(_left||_right)return V;
		    V=speed;
		    V1=i0;
		    if(V>V1){
		    	a= _braCft;
		    	startTime=V/a;
		    	nowTime=startTime-moveRuntime;
		    	t0=	startTime;
		    	t2= nowTime;
				startV=t0*a;
				endV=t2*a;
				if(endV<i0){
					t1=i0;
					endV=i0;
					V0=(startV+endV)/i2;
					V=V0*(t0-t1)/(t0-t2);

				}else{
					V=(startV+endV)/i2;
				}
		       if(_up)
			    	up_speed=endV;
			    else
			    	down_speed=endV;
		    }else{
	    	    if(_up)
			    	up_speed=i0;
			    else
			    	down_speed=i0;
		    	return V1;
		    }
		    return V;	
		}
		public static var i4:int=4;
		public function relaseAccelerator(speed:Number):Number{
		    V=speed;
		    V1=i0;
		    if(V>V1){
		    	a= _braCft/i4;
		    	startTime=V/a;
		    	nowTime=startTime-moveRuntime;
		    	t0=	startTime;
		    	t2= nowTime;
				startV=t0*a;
				endV=t2*a;
				if(endV<i0){
					t1=i0;
					endV=i0;
					V0=(startV+endV)/i2;
					V=V0*(t0-t1)/(t0-t2);
				}else{
					V=(startV+endV)/i2;
				}
		        if(_up)
			    	up_speed=endV;
			    else
			    	down_speed=endV;
		    }else{
	    	    if(_up)
			    	up_speed=i0;
			    else
			    	down_speed=i0;
		    	return V1;
		    }
		    return V;
		}
		public  function moveUp():void{
			if(_brake_down){
				if(up_speed<=i0){
					_speed=i0;
					_up=false;
					_brake_down=false;
					_down=true;
				}else{
					_speed=brake(up_speed);
				}
			}
			else if(_brake){
				if(up_speed<=i0){
					_speed=i0;
				}else{
					_speed=brake(up_speed);	
				}
			}
			else if(_relaseAccelerator){
				if(up_speed<=i0){
					_up=false;
					_speed=i0;
				}else{
					_speed=relaseAccelerator(up_speed);
				}
			}else
			if(_up){
				if(up_speed<carInfo.maxUpSpeed){
					_speed=go(up_speed);
				}else{
					_speed=up_speed;
				}
			}
			sideClipContrl.nextSide(moveRuntime);
//			_x=_x+_vx*moveRuntime;
//			_y=_y+_vy*moveRuntime;
			x_off=_vx*moveRuntime;
			y_off=_vy*moveRuntime;
			confChk.checkConflict(x_off,y_off);
		}

		public  function moveDown():void{
		 
		    if(_brake_up){
				if(down_speed<=i0){
					_speed=i0;
					_down=false;
					_brake_up=false;
					_up=true;
				}else{
					_speed=brake(down_speed);
				}
			}
			else if(_brake){
			    if(down_speed<=i0){
					_speed=i0;
				}else{
					_speed=brake(down_speed);
				}
			}else
		    if(_relaseAccelerator){
				
				if(down_speed<=i0){
					_down=false;
					_speed=i0;
				}else{
					_speed=relaseAccelerator(down_speed);
				}
			}else
			if(_down){
				if(down_speed<carInfo.maxDownSpeed){
					_speed=go(down_speed);
				}else{
					_speed=down_speed;
				}
			}
			sideClipContrl.nextSide(moveRuntime);
//			_x=_x+_vx*moveRuntime;
//			_y=_y+_vy*moveRuntime;
			x_off=_vx*moveRuntime;
			y_off=_vy*moveRuntime;
			confChk.checkConflict(x_off,y_off);
		}
		private var x_off:Number;
		private var y_off:Number;
		public  function moveBySideClip():void{
			sideClipContrl.nextSide(moveRuntime);
			x_off=_vx*moveRuntime;
			y_off=_vy*moveRuntime;
		 	confChk.checkConflict(x_off,y_off);
//			_x=_x+_vx*moveRuntime;
//			_y=_y+_vy*moveRuntime;
		}

        public function destroy():void{
        	//actorDisp.destory();
        	//actorDisp=null;
        	actorDisp.destory();
        	actorDisp=null;
        }
        public function clearSideclip():void{
        	sideClipContrl.hasSideClip=false;
        	sideClipContrl.speed=i0;
        }

}
}